<!--
 * @Author: your name
 * @Date: 2021-04-06 15:49:04
 * @LastEditTime: 2021-05-07 16:47:56
 * @LastEditors: Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /Interview Files/大纲/1110发布订阅.html
-->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>

</html>
<script>
    // 发布订阅模式
    class EventEmitter {
        constructor() {
            // 事件对象，存放订阅的名字和事件
            this.events = {};
        };
        // 订阅事件的方法
        on(eventName, callback) {
            if (!this.events[eventName]) {
                // 注意时数据，一个名字可以订阅多个事件函数
                this.events[eventName] = [callback]
            } else {
                // 存在则push到指定数组的尾部保存
                this.events[eventName].push(callback)
            }
        };
        // 触发事件的方法
        emit(eventName) {
            // 遍历执行所有订阅的事件
            this.events[eventName] && this.events[eventName].forEach(cb => cb());
        };
        // 移除订阅事件
        removeListener(eventName, callback) {
            if (this.events[eventName]) {
                this.events[eventName] = this.events[eventName].filter(cb => cb != callback)
            }
        };
        // 只执行一次订阅的事件，然后移除
        once(eventName, callback) {
            // 绑定的时fn, 执行的时候会触发fn函数
            let fn = () => {
                callback(); // fn函数中调用原有的callback
                this.removeListener(eventName, fn); // 删除fn, 再次执行的时候之后执行一次
            };
            this.on(eventName, fn)
        };
    }
    let em = new EventEmitter();
    let workday = 0;
    em.on("work", function() {
        workday++;
        console.log("work everyday");
    });

    em.once("love", function() {
        console.log("just love you");
    });

    function makeMoney() {
        console.log("make one million money");
    }
    em.on("money", makeMoney);

    let time = setInterval(() => {
        em.emit("work");
        em.removeListener("money", makeMoney);
        em.emit("money");
        em.emit("love");
        if (workday === 5) {
            console.log("have a rest")
            clearInterval(time);
        }
    }, 1);
</script>